package com.chenfan.mcn.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.common.utils.DateUtils;
import com.chenfan.common.vo.UserVO;
import com.chenfan.mcn.clients.baseinfo.*;
import com.chenfan.mcn.clients.privilege.PrivilegeClient;
import com.chenfan.mcn.clients.privilege.SUser;
import com.chenfan.mcn.clients.privilege.SUserVo;
import com.chenfan.mcn.clients.privilege.ScompanyRes;
import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.constant.*;
import com.chenfan.mcn.extension.excel.ExcelCustom;
import com.chenfan.mcn.extension.excel.ExcelHyperlinkDataHolder;
import com.chenfan.mcn.dao.*;
import com.chenfan.mcn.enums.*;
import com.chenfan.mcn.event.EventPublisher;
import com.chenfan.mcn.event.OperateLogEvent;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.common.extension.dict.DictStream;
import com.chenfan.common.extension.dict.DictTranslationUtils;
import com.chenfan.common.extension.util.SmartCompletableFuture;
import com.chenfan.mcn.component.CodeGenerateHelper;
import com.chenfan.mcn.model.*;
import com.chenfan.filestore.vo.FileResult;
import com.chenfan.mcn.model.dto.*;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.service.*;
import com.chenfan.mcn.utils.*;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author liuyang
 * @Date 2021/1/7
 * @Time 20:54
 * @Version V1.0
 **/
@SuppressWarnings("AlibabaMethodTooLong")
@Service
@Slf4j
public class StarBasicDataServiceImpl implements StarBasicDataService {

    @Value("${filestore_download_prefix}")
    private String fileStoreDownloadPrefix;

    @Autowired
    private StarBasicDataMapper starBasicDataMapper;

    @Autowired
    private StarAccountInfoMapper starAccountInfoMapper;

    @Autowired
    private StarContactPersonMapper starContactPersonMapper;

    @Autowired
    private StarPlatformInfoMapper starPlatformInfoMapper;

    @Autowired
    private StarContractMapper starContractMapper;

    @Autowired
    private BaseInfoClient baseInfoClient;

    @Autowired
    private PrivilegeClient privilegeClient;

    @Autowired
    private ContractExcutionOrderMapper contractExcutionOrderMapper;

    @Autowired
    private ApprovalFlowService approvalFlowService;

    @Autowired
    private ContractExcutionOrderService contractExcutionOrderService;

    @Autowired
    private StarBillingHeaderMapper starBillingHeaderMapper;

    private static final Integer THIRTY = 30;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DocKocpmHeaderMapper kocpmHeaderMapper;

    @Autowired
    private DocKocpmRedstarMapper docKocpmRedstarMapper;

    @Resource
    private StarPlatformSettlementInfoMapper starPlatformSettlementInfoMapper;

    @Autowired
    private StarContractDetailMapper starContractDetailMapper;

    /**
     * 红人资料列表
     *
     * @param page      请求参数
     * @param searchDTO 请求参数
     * @return 返回值
     */
    @Override
    public Page<StarBasicDataVO> getList(McnPage<StarBasicDataVO> page, StarBasicDataSearchDTO searchDTO) {
        searchDTO.setAlias("sbd.");
        Page<StarBasicDataVO> pageResult = starBasicDataMapper.getList(page, searchDTO);
        if (CollectionUtils.isNotEmpty(pageResult.getRecords())) {
            DictTranslationUtils.translation(() -> DictStream.of(
                    DictStream.map("active_platforms", StarBasicDataVO::getMainActivePlatforms, StarBasicDataVO::setMainActivePlatforms),
                    DictStream.map("star_label", StarBasicDataVO::getStarLabel, StarBasicDataVO::setStarLabel),
                    DictStream.map("Good_at_type", StarBasicDataVO::getGoodAtType, StarBasicDataVO::setGoodAtType)
                    ), (profileCodes, dictsCodes) -> baseInfoClient.getDescByCode(new DescByCodeDTO(profileCodes, dictsCodes)).getObj(), pageResult.getRecords()
            );
            List<Long> starAgentIds = pageResult.getRecords().stream().map(StarBasicDataVO::getStarAgentId).distinct().collect(Collectors.toList());
            List<SUserVo> sUserVos = Objects.requireNonNull(privilegeClient.getDepartmentByUserIds(starAgentIds)).getObj();
            if (CollectionUtils.isNotEmpty(sUserVos)) {
                Map<Long, SUserVo> sUserVoMap = sUserVos.stream().collect(Collectors.toMap(SUserVo::getUserId, Function.identity()));
                pageResult.getRecords().forEach(x -> {
                    if (Objects.nonNull(x.getStarAgentId())) {
                        SUserVo sUserVo = sUserVoMap.get(x.getStarAgentId());
                        x.setStarAgentName(Objects.nonNull(sUserVo) ? sUserVo.getUsername() : "");
                    }
                });
            }
        }
        return pageResult;
    }

    /**
     * 删除红人资料信息
     *
     * @param starId 请求参数
     * @return 返回值
     */
    @Override
    public int delete(Long starId) {
        StarBasicData entity = starBasicDataMapper.selectById(starId);
        BusinessAssert.notNull(entity, McnErrorCode.STAR_BASIC_DATA_IS_NULL);
        StarBasicData updateEntity = new StarBasicData();
        updateEntity.setId(entity.getId());
        updateEntity.setIsDelete(NumberCst.ONE);
        return starBasicDataMapper.updateById(updateEntity);
    }

    /**
     * 详情
     *
     * @param starId 请求参数
     * @return 返回值
     */
    @Override
    public StarBasicDataInfoVO info(Long starId) {
        StarBasicData starBasicData = starBasicDataMapper.selectById(starId);
        if (Objects.isNull(starBasicData)) {
            return null;
        }
        SUser sUser = Objects.requireNonNull(privilegeClient.getUserById(starBasicData.getStarAgentId())).getObj();
        if (Objects.nonNull(sUser)) {
            starBasicData.setStarAgentName(sUser.getUsername());
        }
        StarBasicDataInfoVO starBasicDataInfoVO = new StarBasicDataInfoVO();
        BeanUtils.copyProperties(starBasicData, starBasicDataInfoVO);
        List<StarAccountInfoVO> starAccountInfo = starAccountInfoMapper.info(starId);
        if (Objects.nonNull(starAccountInfo)) {
            setStarAccountInfoDirects(starAccountInfo);
            starBasicDataInfoVO.setStarAccountInfos(starAccountInfo);
        }
        List<StarContactPerson> starContactPerson = starContactPersonMapper.info(starId);
        if (Objects.nonNull(starContactPerson)) {
            starBasicDataInfoVO.setStarContactPersonList(starContactPerson);
        }
        List<StarPlatformInfo> starPlatformInfoList = starPlatformInfoMapper.info(starId);
        if (CollectionUtils.isNotEmpty(starPlatformInfoList)) {
            //我司合同主体
            Map<Long, String> companyMap = CommonUtil.defaultList(privilegeClient.getParList().getObj()).
                    stream().collect(Collectors.toMap(ScompanyRes::getCompanyId, ScompanyRes::getParentCompanyName));
            for (StarPlatformInfo platform : starPlatformInfoList) {
                List<StarPlatformSettlementInfo> starPlatformSettlementInfos = starPlatformSettlementInfoMapper.selectList(Wrappers.lambdaQuery(StarPlatformSettlementInfo.class)
                        .eq(StarPlatformSettlementInfo::getStarPlatformInfoId, platform.getId())
                        .eq(StarPlatformSettlementInfo::getIsDelete, NumberCst.ZERO));
                platform.setSettlementInfos(starPlatformSettlementInfos);
                if(Objects.nonNull(platform.getContractingId()) && CommonUtil.containsKey(companyMap, platform.getContractingId())) {
                    platform.setCompanyContractSubject(companyMap.get(platform.getContractingId()));
                }
            }
            setStarPlatformInfoDirects(starPlatformInfoList);
            starBasicDataInfoVO.setStarPlatformInfos(starPlatformInfoList);
        }

        List<StarContract> starContracts = starContractMapper.selectList(Wrappers.lambdaQuery(StarContract.class).eq(StarContract::getStarId, starId).eq(StarContract::getIsDelete, Boolean.FALSE));
        if (CollectionUtils.isNotEmpty(starContracts)) {
            List<Long> starContractIds = starContracts.stream().map(StarContract::getId).collect(Collectors.toList());
            List<StarContractDetailVO> starContractDetailList = CommonUtil.defaultList(starContractDetailMapper.selectList(
                    Wrappers.lambdaQuery(StarContractDetail.class).in(StarContractDetail::getStarContractId, starContractIds).eq(StarContractDetail::getIsDelete, NumberCst.ZERO)
                    .orderByDesc(StarContractDetail::getSigningStartTime)
            )).stream().map(e -> {
                StarContractDetailVO vo = new StarContractDetailVO();
                BeanUtils.copyProperties(e, vo);
                return vo;
            }).collect(Collectors.toList());
            Map<Long, List<StarContractDetailVO>> starContractDetailMap = CommonUtil.defaultList(starContractDetailList).stream().collect(Collectors.groupingBy(StarContractDetail::getStarContractId));
            List<Long> starPlatformIds =  CommonUtil.defaultList(starContractDetailList).stream().map(StarContractDetailVO::getStarPlatformId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            Map<Long, StarPlatformInfo> starPlatformInfoMap = CommonUtil.defaultList(
                    CommonUtil.supplyIfNecessary(CollectionUtils.isNotEmpty(starPlatformIds), () -> starPlatformInfoMapper.selectList(Wrappers.lambdaQuery(StarPlatformInfo.class).in(StarPlatformInfo::getId, starPlatformIds).eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO)))
            ).stream().collect(Collectors.toMap(StarPlatformInfo::getId, Function.identity()));
            Date now = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
            List<StarContractVO> starContractVos = starContracts.stream().map(starContract -> {
                StarContractVO vo = new StarContractVO();
                BeanUtils.copyProperties(starContract, vo);
                vo.setStarContractDetails(CommonUtil.getMapValue(starContractDetailMap, vo.getId()));
                if (vo.getState() == 1) {
                    vo.setStateName("已解约");
                } else if (vo.getState() == 0 && this.withInTimeRange(now, vo.getStarContractDetails())) {
                    vo.setStateName("生效中");
                } else if (vo.getState() == 0 && this.beforeTimeRange(now, vo.getStarContractDetails())) {
                    vo.setStateName("已失效");
                } else {
                    vo.setStateName("未生效");
                }
                if(CollectionUtils.isNotEmpty(vo.getStarContractDetails())) {
                    vo.getStarContractDetails().forEach(e -> {
                        StarPlatformInfo starPlatformInfo = starPlatformInfoMap.get(e.getStarPlatformId());
                        if(Objects.nonNull(starPlatformInfo)) {
                            e.setPlatformId(starPlatformInfo.getPlatformId());
                            e.setPlatformName(starPlatformInfo.getPlatformName());
                            e.setPlatNickName(starPlatformInfo.getPlatNickName());
                        }
                    });
                }
                return vo;
            }).collect(Collectors.toList());
            DictTranslationUtils.translation(() -> DictStream.of(
                    DictStream.map(DictTypeCst.SIGN_CONTRACT_TYPE, StarContractVO::getContractType, StarContractVO::setContractTypeName)
                    ), (profileCodes, dictsCodes) -> baseInfoClient.getDescByCode(new DescByCodeDTO(profileCodes, dictsCodes)).getObj(), starContractVos
            );
            starBasicDataInfoVO.setStarContracts(starContractVos);
        }
        List<StarBillingHeader> starBillingHeaders = starBillingHeaderMapper.selectList(Wrappers.lambdaQuery(StarBillingHeader.class).eq(StarBillingHeader::getStarId, starId).eq(StarBillingHeader::getIsDelete, Boolean.FALSE));
        starBasicDataInfoVO.setStarBillingHeaders(starBillingHeaders);
        //字典翻译
        DictTranslationUtils.translation(() -> DictStream.of(
                DictStream.map("Recommended_index", StarBasicDataInfoVO::getIndexRecommendation, StarBasicDataInfoVO::setRecommendedIndexName),
                DictStream.map("Matching_degree", StarBasicDataInfoVO::getMatchingDegree, StarBasicDataInfoVO::setMatchingDegreeName),
                DictStream.map("star_nature", StarBasicDataInfoVO::getStarProperty, StarBasicDataInfoVO::setStarNatureName),
                DictStream.map("star_source", StarBasicDataInfoVO::getStarSource, StarBasicDataInfoVO::setStarSourceName),
                DictStream.map("active_platforms", StarBasicDataInfoVO::getMainActivePlatforms, StarBasicDataInfoVO::setActivePlatformsName),
                DictStream.map("star_label", StarBasicDataInfoVO::getStarLabel, StarBasicDataInfoVO::setStarLabelName),
                DictStream.map("Good_at_type", StarBasicDataInfoVO::getGoodAtType, StarBasicDataInfoVO::setGoodAtTypeName),
                DictStream.map("star_classification", StarBasicDataInfoVO::getStarClassification, StarBasicDataInfoVO::setStarClassificationName)
                ),(dictProfileList, dictList) -> baseInfoClient.getDescByCode(new DescByCodeDTO(dictProfileList, dictList)).getObj(),
                starBasicDataInfoVO
        );
        return starBasicDataInfoVO;
    }


    /**
     * 红人收款账号信息详情字段获取数据库字典
     *
     * @param starAccountInfo 请求参数
     */
    public void setStarAccountInfoDirects(List<StarAccountInfoVO> starAccountInfo) {
        List<String> dictProfileList = new ArrayList<>();
        dictProfileList.add("account_type");
        List<String> dictList = starAccountInfo.stream().map(StarAccountInfoVO::getAccountType).distinct().collect(Collectors.toList());
        Map<String, String> dictMapping = Objects.requireNonNull(baseInfoClient.getDescByCode(new DescByCodeDTO().setDictsCodes(dictList).setProfileCodes(dictProfileList))).getObj();
        if (Objects.nonNull(dictMapping)) {
            starAccountInfo.forEach(vo -> vo.setAccountTypeName(dictMapping.get(dictProfileList.get(0) + ";" + vo.getAccountType())));
        }
    }

    /**
     * 红人所在平台信息详情字段获取数据库字典
     *
     * @param starPlatformInfo 请求参数
     */
    public void setStarPlatformInfoDirects(List<StarPlatformInfo> starPlatformInfo) {
        Map<String, Map<String, String>> secondlevelDictMap = baseInfoClient.getAllSecondlevelDictMap(DictTypeCst.ACTIVE_PLATFORMS);
        for (StarPlatformInfo vo : starPlatformInfo) {
            List<StarPlatformSettlementInfo> settlementInfos = vo.getSettlementInfos();
            if (CollectionUtils.isNotEmpty(settlementInfos)) {
                settlementInfos.forEach(settlementInfo -> {
                    settlementInfo.setCooperationContentName(CommonUtil.getMapValue(secondlevelDictMap.get(vo.getPlatformId()), settlementInfo.getCooperationContent()));
                });
            }
        }
    }

    /**
     * 导出列表数据
     *
     * @param basicDataDto 请求参数
     * @param response     请求参数
     * @return
     */
    @Override
    public List<StarBasicDataExportVO> exportExcel(StarBasicDataSearchDTO basicDataDto, HttpServletResponse response) throws Exception {
        List<StarBasicDataExportVO> list = starBasicDataMapper.exportList(basicDataDto);
        if (CollectionUtils.isNotEmpty(list)) {
            //字典翻译
            /*DictTranslationUtils.translation(() -> DictStream.of(
                    DictStream.map("star_source", StarBasicDataExportVO::getStarSource, StarBasicDataExportVO::setStarSource),
                    DictStream.map("star_nature", StarBasicDataExportVO::getStarProperty, StarBasicDataExportVO::setStarProperty),
                    DictStream.map("TypeContract", StarBasicDataExportVO::getContractType, StarBasicDataExportVO::setContractType),
                    DictStream.map("Signing_platform", StarBasicDataExportVO::getSignPlatform, StarBasicDataExportVO::setSignPlatform),
                    DictStream.map("active_platforms", StarBasicDataExportVO::getMainActivePlatforms, StarBasicDataExportVO::setMainActivePlatforms),
                    DictStream.map("star_label", StarBasicDataExportVO::getStarLabel, StarBasicDataExportVO::setStarLabel),
                    DictStream.map("Good_at_type", StarBasicDataExportVO::getGoodAtType, StarBasicDataExportVO::setGoodAtType),
                    DictStream.map("star_classification", StarBasicDataExportVO::getStarClassification, StarBasicDataExportVO::setStarClassification)
                    ), (profileCodes, dictsCodes) -> baseInfoClient.getDescByCode(new DescByCodeDTO(profileCodes, dictsCodes)).getObj(), list
            );
            list.forEach(vo -> {
                if (StringUtils.isNotBlank(vo.getStarAddress())) {
                    vo.setStarAddress(StringUtils.join(JSONObject.parseObject(vo.getStarAddress(), new TypeReference<List<String>>() {
                    }), SeparatorCst.COMMA));
                }
            });*/
        }
        return list;
    }

    @Override
    public void exportExecuteOrderExcel(StarBasicDataSearchDTO basicDataDto, HttpServletResponse response) throws Exception {
        List<ExcutionExportVO> dataList = new ArrayList<>(0);
        List<StarBasicDataExportVO> orderList = exportExcel(basicDataDto, response);
        if (CollectionUtils.isNotEmpty(orderList)) {
            List<Long> starCodeList = new ArrayList<>();
            for (StarBasicDataExportVO bean : orderList) {
                starCodeList.add(Long.valueOf(bean.getId()));
            }
            Double ceil = Math.ceil(Double.valueOf(starCodeList.size()) / Double.valueOf(100));
            List<CompletableFuture> completableFutureList = new ArrayList<>();
            Long tenantId = UserVoContextHolder.getTenantId();
            for (int i = 0; i < ceil; i++) {
                ExcutionOrderSearchDTO excutionOrderSearchDTO = new ExcutionOrderSearchDTO();
                if (i == ceil.intValue() - 1) {
                    excutionOrderSearchDTO.setStarIds(starCodeList.subList(100 * i, starCodeList.size()));
                } else {
                    excutionOrderSearchDTO.setStarIds(starCodeList.subList(100 * i, (100 * (i + 1))));
                }
                excutionOrderSearchDTO.setExportTypes("0,1,3");
                excutionOrderSearchDTO.setTenantId(tenantId);
                completableFutureList.add(SmartCompletableFuture.supplyAsync(() ->
                        contractExcutionOrderService.export(excutionOrderSearchDTO)
                ).whenComplete((v, t) -> {
                    if (CollectionUtils.isNotEmpty(v)) {
                        dataList.addAll(v);
                    }
                }));
            }
            SmartCompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[]{})).join();
        }
        //获取自定义的导出字段
        List<ExcelCustom> excelCustomList = contractExcutionOrderService.chooseExportField("0,1,3");
        ExcelUtils.customExport("执行单导出.xlsx", null, "收入合同执行单", excelCustomList, ExcutionExportVO.class, dataList, response);
    }


    /**
     * 导出-红人平台信息
     *
     * @param basicDataDto 请求参数
     * @param response     请求参数
     * @throws Exception
     */
    @Override
    public void exportPlatformInfo(StarBasicDataSearchDTO basicDataDto, HttpServletResponse response) throws Exception {
        List<StarPlatformExportVO> list = starBasicDataMapper.exportPlatformInfo(basicDataDto);
        if (CollectionUtils.isNotEmpty(list)) {
            Map<String, Map<String, String>> dictMap = CommonUtil.defaultList(baseInfoClient.getSecondDictList(DictTypeCst.ACTIVE_PLATFORMS, false).getObj())
                    .stream().collect(Collectors.toMap(k -> k.getDictsCode(), v ->
                            CommonUtil.defaultList(v.getThirdDictList()).stream().collect(Collectors.toMap(BaseSecondlevelDictsVO::getSecondlevelCode, BaseSecondlevelDictsVO::getSecondlevelDictsNameC))
                    ));
            //我司合同主体
            Map<Long, String> companyMap = CommonUtil.defaultList(privilegeClient.getParList().getObj()).
                    stream().collect(Collectors.toMap(ScompanyRes::getCompanyId, ScompanyRes::getParentCompanyName));
            for (StarPlatformExportVO vo : list) {
                if(CollectionUtils.isEmpty(vo.getSecondList())) {
                    continue;
                }
                vo.getSecondList().forEach(e -> {
                    Map<String, String> subDictMap = dictMap.get(e.getPlatformId());
                    if(MapUtils.isNotEmpty(subDictMap)) {
                        CommonUtil.defaultList(e.getThirdList()).forEach(t -> {
                            t.setCooperationContentName(subDictMap.get(t.getCooperationContent()));
                        });
                    }
                    if(Objects.nonNull(e.getContractingId()) && CommonUtil.containsKey(companyMap, e.getContractingId())) {
                        e.setCompanyContractSubject(companyMap.get(e.getContractingId()));
                    }
                });
            }
        }
        ExcelUtils.exportExcel(CommonUtil.defaultList(list), "红人平台信息导出", StarPlatformExportVO.class, "红人平台信息导出.xlsx", response);
    }

    /**
     * 新增红人基础档案
     *
     * @param starBasicDataDTO 请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveData(StarBasicDataDTO starBasicDataDTO) throws BusinessException {
        starBasicDataDTO.setIdCard(StringUtils.trim(starBasicDataDTO.getIdCard()));
        starBasicDataDTO.setStarNickname(StringUtils.trim(starBasicDataDTO.getStarNickname()));
        //按红人类型校验红人昵称证是否重复
        this.verifyDuplicateNickname(starBasicDataDTO.getStarNickname(), starBasicDataDTO.getStarType(), null);
        //按红人类型校验红人身份证是否重复
        this.verifyDuplicateIdNumber(starBasicDataDTO.getIdCardType(), starBasicDataDTO.getIdCard(),null);
        //校验红人平台结算信息的合作内容是否重复
        this.verifyDuplicateCooperationContent(starBasicDataDTO);
        StarBasicData starBasicData = BaseAssemblerUtil.copyIgnoreBase(starBasicDataDTO, new StarBasicData());
        int count = assemblyStarBasicData(starBasicData);
        if (count > 0) {
            Long starId = starBasicData.getId();
            assemblyStarAccountInfo(starId, starBasicDataDTO);
            assemblyStarContactPerson(starId, starBasicDataDTO);
            assemblyStarPlatformInfo(starId, starBasicDataDTO);
            assemblyStarContract(starId, starBasicDataDTO);
            assemblyStarBillingHeader(starId, starBasicDataDTO);
            return starBasicData.getId();
        }
        throw new BusinessException(McnErrorCode.DATA_INSERT_ERROR);
    }

    /**
     * 校验红人平台结算信息的合作内容是否重复
     *
     * @param starBasicDataDTO
     */
    private void verifyDuplicateCooperationContent(StarBasicDataDTO starBasicDataDTO) {
        List<StarPlatformInfo> starPlatformInfos = starBasicDataDTO.getStarPlatformInfos();
        if (CollUtil.isNotEmpty(starPlatformInfos)) {
            for (StarPlatformInfo starPlatformInfo : starPlatformInfos) {
                List<StarPlatformSettlementInfo> settlementInfos = starPlatformInfo.getSettlementInfos();
                if (CollUtil.isNotEmpty(settlementInfos)) {
                    for (StarPlatformSettlementInfo settlement:settlementInfos) {
                        //BusinessAssert.isTrue(settlement.getDevidedRate().compareTo(BigDecimal.ZERO) >= 0 && settlement.getDevidedRate().scale() <= 2, McnErrorCode.PARAM_ERROR, "请正确输入-分成比例（>=0 且 小数位<=2）");
                        //BusinessAssert.maxLength(settlement.getDevidedRemark(), 100, McnErrorCode.PARAM_ERROR, "分成备注长度最大不能超出%s个字符");
                        BusinessAssert.maxLength(settlement.getAssessRequirement(), 500, McnErrorCode.PARAM_ERROR, "考核要求长度最大不能超出%s个字符");
                    }
                    Map<String, List<StarPlatformSettlementInfo>> groupByCooperationContentMap = settlementInfos.stream().collect(Collectors.groupingBy(StarPlatformSettlementInfo::getCooperationContent));
                    for (Map.Entry<String, List<StarPlatformSettlementInfo>> entry : groupByCooperationContentMap.entrySet()) {
                        BusinessAssert.isFalse(entry.getValue().size() > NumberCst.ONE, McnErrorCode.DUPLICATE_PLATFORM_SETTLEMENT_COOPERATION_CONTENT);
                    }
                }
            }
        }
    }

    /**
     * 修改红人基础资料
     * @param starBasicDataDTO 请求参数
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateData(StarBasicDataDTO starBasicDataDTO) {
        Long starId = starBasicDataDTO.getId();
        BusinessAssert.notNull(starId, McnErrorCode.PARAM_ERROR, "红人ID不能为空");
        StarBasicData entity = starBasicDataMapper.selectOne(Wrappers.lambdaQuery(StarBasicData.class)
                .eq(StarBasicData::getId, starId)
                .eq(StarBasicData::getIsDelete, Boolean.FALSE));
        BusinessAssert.notNull(entity, McnErrorCode.DATA_NOT_FOUND, "查询不到该红人信息");
        starBasicDataDTO.setIdCard(StringUtils.trim(starBasicDataDTO.getIdCard()));
        starBasicDataDTO.setStarNickname(StringUtils.trim(starBasicDataDTO.getStarNickname()));
        //按红人类型校验红人昵称是否重复
        this.verifyDuplicateNickname(starBasicDataDTO.getStarNickname(), starBasicDataDTO.getStarType(), starId);
        //按红人类型校验红人身份证是否重复
        if(NumberCst.ZERO.equals(entity.getStarStatus())) {
            this.verifyDuplicateIdNumber(starBasicDataDTO.getIdCardType(), starBasicDataDTO.getIdCard(), starId);
        }
        // 校验红人平台结算信息的合作内容是否重复
        this.verifyDuplicateCooperationContent(starBasicDataDTO);
        //校验红人类型变更
        this.verifyChangeStarType(starId, entity.getStarType(), starBasicDataDTO.getStarType());
        StarBasicData starBasicData = BaseAssemblerUtil.copyIgnoreBase(starBasicDataDTO, new StarBasicData());
        boolean result = starBasicDataMapper.updateById(starBasicData) > 0;
        if (result) {
            //操作日志
            EventPublisher.post(OperateLogEvent.builder().businessId(entity.getId())
                    .businessType(LogBusinessTypeEnum.STAR_INFO)
                    .compare(entity, starBasicDataMapper.selectById(entity.getId()))
                    .build());
            //红人关联表编辑
            editStarAccountInfo(starId, starBasicDataDTO);
            editStarContactPerson(starId, starBasicDataDTO);
            editStarPlatformInfo(starId, starBasicDataDTO);
            editStarContract(starId, starBasicDataDTO);
            editStarBillingHeader(starId, starBasicDataDTO);
        }
        return starId;
    }


    /**
     * 红人执行单列表
     *
     * @param page   {@link McnPage}
     * @param starId {@link Long}
     * @return
     */
    @Override
    public Page<StarExecutionVO> executionList(McnPage<StarExecutionVO> page, Long starId) {
        Page<StarExecutionVO> list = contractExcutionOrderMapper.executionList(page, starId, ApprovalEnum.getExecutionOrderProcessIds());
        if (Objects.nonNull(list)) {
            List<Long> flowList = list.getRecords().stream().map(StarExecutionVO::getFlowId).filter(Objects::nonNull).collect(Collectors.toList());
            JSONObject flowMapping = null;
            if (flowList.size() > 0) {
                flowMapping = approvalFlowService.getFlowStatus(flowList);
            }
            JSONObject finalFlowMapping = flowMapping;

            list.getRecords().forEach(record -> {
                if (Objects.nonNull(finalFlowMapping) && finalFlowMapping.size() > 0 && Objects.nonNull(record.getFlowId())) {
                    record.setFlowStatusName(finalFlowMapping.getString(record.getFlowId().toString()));
                }
            });
        }
        return list;
    }

    @Override
    public void updateStatus(Long id, Integer starStatus) {
        StarBasicData starBasicData = starBasicDataMapper.selectById(id);
        BusinessAssert.notNull(starBasicData, McnErrorCode.STAR_BASIC_DATA_IS_NULL);
        //按红人类型校验红人身份证是否重复
        if(NumberCst.ZERO.equals(starStatus)) {
            this.verifyDuplicateIdNumber(starBasicData.getIdCardType(), starBasicData.getIdCard(), id);
        }
        starBasicDataMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarBasicData.class)
                .set(StarBasicData::getStarStatus, starStatus)
                .eq(StarBasicData::getId, id));
        //操作日志
        EventPublisher.post(OperateLogEvent.builder().businessId(id)
                .businessType(LogBusinessTypeEnum.STAR_INFO)
                .compare(starBasicData, starBasicDataMapper.selectById(id))
                .build());
    }

    @Override
    public void updatePlatformSettlementStatus(Long id, Integer starStatus) {
        starPlatformSettlementInfoMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarPlatformSettlementInfo.class)
                .set(StarPlatformSettlementInfo::getStatus, starStatus)
                .eq(StarPlatformSettlementInfo::getId, id));
    }

    @Override
    public List<StarPlatformSettlementInfo> getPlatSettlementsByPlatId(Long platformId) {
        List<StarPlatformSettlementInfo> starPlatformSettlementInfos = starPlatformSettlementInfoMapper.selectList(Wrappers.lambdaQuery(StarPlatformSettlementInfo.class)
                .eq(StarPlatformSettlementInfo::getStarPlatformInfoId, platformId).eq(StarPlatformSettlementInfo::getIsDelete, Boolean.FALSE)
                .eq(StarPlatformSettlementInfo::getStatus, NumberCst.ONE));
        if (CollUtil.isNotEmpty(starPlatformSettlementInfos)) {
            for (StarPlatformSettlementInfo settlement : starPlatformSettlementInfos) {
                String nameC = baseInfoClient.getTargetDictNameByCode(settlement.getCooperationContent()).getObj();
                settlement.setCooperationContentName(nameC);
            }
        }
        return starPlatformSettlementInfos;
    }

    @Override
    public List<StarSignContractExportVO> exportSignContract(StarBasicDataSearchDTO basicDataDto) {
        List<StarSignContractExportVO> dataList = starBasicDataMapper.exportSignContract(basicDataDto);
        if(CollectionUtils.isNotEmpty(dataList)) {
            DictTranslationUtils.translation(() -> DictStream.of(
                    DictStream.map(DictTypeCst.SIGN_CONTRACT_TYPE, StarSignContractExportVO::getContractType, StarSignContractExportVO::setContractType)
                    ), (profileCodes, dictsCodes) -> baseInfoClient.getDescByCode(new DescByCodeDTO(profileCodes, dictsCodes)).getObj(), dataList
            );
            Date now = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
            dataList.forEach(e -> {
                if (e.getState() == 1) {
                    e.setStateName("已解约");
                } else if (e.getState() == 0 && !now.before(e.getSigningStartTime()) && !now.after(e.getSigningEndTime())) {
                    e.setStateName("生效中");

                } else if (e.getState() == 0 && now.after(e.getSigningEndTime())) {
                    e.setStateName("已失效");
                } else {
                    e.setStateName("未生效");
                }
                if(StringUtils.isNotBlank(e.getContract())) {
                    List<FileResult> fileResultList = JSONObject.parseObject(e.getContract(), new TypeReference<List<FileResult>>(){});
                    if(CollectionUtils.isNotEmpty(fileResultList)) {
                        for (int i = 0; i < fileResultList.size(); i++) {
                            String address = fileStoreDownloadPrefix+fileResultList.get(i).getId();
                            String fileName = fileResultList.get(i).getFileName();
                            ExcelHyperlinkDataHolder.add(address, fileName);
                            switch (i) {
                                case 0:
                                    e.setContract1(fileName);
                                    e.setAddress1(address);
                                    break;
                                case 1:
                                    e.setContract2(fileName);
                                    e.setAddress2(address);
                                    break;
                                case 2:
                                    e.setContract3(fileName);
                                    e.setAddress3(address);
                                    break;
                                case 3:
                                    e.setContract4(fileName);
                                    e.setAddress4(address);
                                    break;
                                case 4:
                                    e.setContract5(fileName);
                                    e.setAddress5(address);
                                    break;
                            }
                        }
                    }
                }
            });
        }
        return dataList;
    }

    @Override
    public List<StarNickNameVO> getStarNickNamesByIds(List<Long> starIds) {
        List<StarBasicData> dataList = CommonUtil.defaultList(starBasicDataMapper.selectList(Wrappers.lambdaQuery(StarBasicData.class)
                .select(StarBasicData::getId, StarBasicData::getStarNickname)
                .in(StarBasicData::getId, starIds)));
        return dataList.stream().map(e -> {
            StarNickNameVO starNickNameVO = new StarNickNameVO();
            starNickNameVO.setStarId(e.getId());
            starNickNameVO.setNickName(e.getStarNickname());
            return starNickNameVO;
        }).collect(Collectors.toList());
    }

    /**
     * 目前需求-红人基础信息-KOC项目-红人平台信息-红人账户信息 都是1对1对1，不存在数据聚合（除了关联KOC项目）
     *
     * @param inputList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importKocExcel(List<KocStarInputDTO> inputList) {
        //1、校验参数
        List<String> repeatedVoucher = new ArrayList<>(inputList.size());
        List<KocStarOutputDTO> outputList = inputList.stream().map(e -> {
            KocStarOutputDTO outputDTO = new KocStarOutputDTO();
            BeanUtils.copyProperties(e, outputDTO);
            outputDTO.setFailedReason(ValidatorUtil.getJointValidateResult(outputDTO, SeparatorCst.LINE_BREAK));
            if (StringUtils.isBlank(outputDTO.getFailedReason())) {
                String voucher = StringUtils.joinWith(SeparatorCst.PLUS, e.getStarNickname(), e.getStarName());
                if (repeatedVoucher.contains(voucher)) {
                    outputDTO.setFailedReason(CommonUtil.joinWith(SeparatorCst.LINE_BREAK, outputDTO.getFailedReason(), String.format("【%s】重复", voucher)));
                } else {
                    outputDTO.setVoucher(voucher);
                    repeatedVoucher.add(voucher);
                }
            }
            return outputDTO;
        }).collect(Collectors.toList());
        //2、校验系统数据匹配校验
        List<String> starNicknameList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getStarNickname())).map(KocStarOutputDTO::getStarNickname).distinct().collect(Collectors.toList());
        List<String> starNameList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getStarName())).map(KocStarOutputDTO::getStarName).distinct().collect(Collectors.toList());
        List<String> starAgentNameList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getStarAgentName())).map(KocStarOutputDTO::getStarAgentName).distinct().collect(Collectors.toList());
        List<String> kocpmNameList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getKocpmName())).map(KocStarOutputDTO::getKocpmName).distinct().collect(Collectors.toList());
        List<DocKocpmHeader> kocpmHeaderList = CommonUtil.supplyIfNecessary(CollectionUtils.isNotEmpty(kocpmNameList), () ->
                kocpmHeaderMapper.selectList(Wrappers.lambdaQuery(DocKocpmHeader.class)
                        .select(DocKocpmHeader::getKocpmId, DocKocpmHeader::getKocpmName).in(DocKocpmHeader::getKocpmName, kocpmNameList)
                        .eq(DocKocpmHeader::getStatus, NumberCst.ZERO)));
        Map<String, Long> kocpmMap = CommonUtil.defaultList(kocpmHeaderList).stream().collect(Collectors.toMap(k -> k.getKocpmName(), v -> v.getKocpmId()));
        Map<String, SUserVo> userMap = privilegeClient.getUserMapByName(starAgentNameList);
        Map<String, String> platforNameMap = CommonUtil.defaultList(RpcUtil.getObjException(baseInfoClient.getDictList("active_platforms"),
                "所在平台-数据字典信息，查询异常")).stream().filter(e -> !e.getDictsStatus().booleanValue()).collect(Collectors.toMap(k -> k.getDictsNameC(), v -> v.getDictsCode()));
        List<StarBasicData> kocStarList = CommonUtil.supplyIfNecessary(CollectionUtils.isNotEmpty(starNicknameList) && CollectionUtils.isNotEmpty(starNameList), () ->
                starBasicDataMapper.selectList(Wrappers.lambdaQuery(StarBasicData.class)
                        .select(StarBasicData::getStarNickname, StarBasicData::getStarName, StarBasicData::getStarType)
                        .in(StarBasicData::getStarNickname, starNicknameList).in(StarBasicData::getStarName, starNameList)
                        .eq(StarBasicData::getStarType, StarTypeEnum.KOC.getCode()).eq(StarBasicData::getIsDelete, NumberCst.ZERO)));
        Map<String, StarBasicData> kocStarMap = CommonUtil.defaultList(kocStarList)
                .stream().collect(Collectors.toMap(k -> StringUtils.joinWith(SeparatorCst.PLUS, k.getStarNickname(), k.getStarName()), v -> v));
        outputList.forEach(e -> e.verifySysDataMatch(kocStarMap, kocpmMap, userMap, platforNameMap, SeparatorCst.LINE_BREAK));
        if (outputList.stream().filter(e -> StringUtils.isNotBlank(e.getFailedReason())).count() > 0L) {
            return generateDownloadFiledId(outputList, ImportExcelEnum.KOC_STAR);
        }
        //批量插入KOC红人数据
        List<StarBasicData> starBasicDataList = outputList.stream().map(e -> {
            StarBasicData starBasicData = new StarBasicData();
            e.fillStarBasicData(userMap.get(e.getStarAgentName()), starBasicData);
            return starBasicData;
        }).collect(Collectors.toList());
        Lists.partition(starBasicDataList, McnConstant.MAX_INSERT_SIZE).forEach(subList -> {
            List<String> starCodeList = CodeGenerateHelper.getCodes(BillCodeCst.STAR_BASIC, subList.size());
            BusinessAssert.isTrue(subList.size() == starCodeList.size(), McnErrorCode.BUSINESS_ERROR, "批量获取的红人编号数量不对！");
            for (int i = 0; i < subList.size(); i++) {
                subList.get(i).setStarCode(starCodeList.get(i));
            }
            starBasicDataMapper.insertBatch(subList);
        });
        Map<String, StarBasicData> insertStarMap = starBasicDataList.stream().collect(Collectors.toMap(k -> StringUtils.joinWith(SeparatorCst.PLUS, k.getStarNickname(), k.getStarName()), v -> v));
        //批量插入红人所在平台信息
        List<StarPlatformInfo> starPlatformInfoList = outputList.stream().map(e -> {
            StarPlatformInfo starPlatformInfo = new StarPlatformInfo();
            e.fillStarPlatformInfo(insertStarMap.get(e.getVoucher()), platforNameMap.get(e.getPlatformName()), starPlatformInfo);
            return starPlatformInfo;
        }).collect(Collectors.toList());
        Lists.partition(starPlatformInfoList, McnConstant.MAX_INSERT_SIZE).forEach(subList -> {
            starPlatformInfoMapper.insertBatch(subList);
        });
        //批量插入红人收款账号信息
        List<StarAccountInfo> starAccountInfoList = outputList.stream().map(e -> {
            StarAccountInfo starAccountInfo = new StarAccountInfo();
            e.fillStarAccountInfo(insertStarMap.get(e.getVoucher()), starAccountInfo);
            return starAccountInfo;
        }).collect(Collectors.toList());
        Lists.partition(starAccountInfoList, McnConstant.MAX_INSERT_SIZE).forEach(subList -> {
            starAccountInfoMapper.insertBatch(subList);
        });
        //批量插入KOC红人与-KOC项目关联
        Map<Long, List<StarPlatformInfo>> starPlatformInfoMap = starPlatformInfoList.stream().collect(Collectors.groupingBy(StarPlatformInfo::getStarId));
        List<DocKocpmRedstar> docKocpmRedstarList = new ArrayList<>(starPlatformInfoList.size());
        outputList.forEach(e -> {
            StarBasicData starBasicData = insertStarMap.get(e.getVoucher());
            List<StarPlatformInfo> starPlatformInfos = starPlatformInfoMap.get(starBasicData.getId());
            starPlatformInfos.forEach(starPlatformInfo -> {
                DocKocpmRedstar docKocpmRedstar = new DocKocpmRedstar();
                docKocpmRedstar.setKocpmId(kocpmMap.get(e.getKocpmName()));
                docKocpmRedstar.setExcuteMoney(e.getExcuteMoney());
                docKocpmRedstar.setStarPlatformInfoId(starPlatformInfo.getId());
                docKocpmRedstar.setCreateBy(UserVoContextHolder.getUserId());
                docKocpmRedstar.setCreateName(UserVoContextHolder.getUserName());
                docKocpmRedstar.setCompanyId(UserVoContextHolder.getCompanyId());
                docKocpmRedstar.setTenantId(UserVoContextHolder.getTenantId());
                docKocpmRedstarList.add(docKocpmRedstar);
            });
        });
        Lists.partition(docKocpmRedstarList, McnConstant.MAX_INSERT_SIZE).forEach(subList -> {
            docKocpmRedstarMapper.insertBatch(subList);
        });
        return null;
    }

    @Override
    public void downloadKocFailedReason(HttpServletResponse response, String fileId) {
        BusinessAssert.isTrue(ImportExcelEnum.match(fileId, ImportExcelEnum.KOC_STAR), McnErrorCode.EXPORT_FILE_ID_ILLEGAL);
        // 根据FileId判断导出类型
        String excelContent = CommonUtil.defaultIfEmpty(stringRedisTemplate.opsForValue().get(McnConstant.CACHE_PRIFIX + fileId));
        List<KocStarOutputDTO> outputList = JSONObject.parseObject(excelContent, new TypeReference<List<KocStarOutputDTO>>() {
        });
        BusinessAssert.notEmpty(outputList, McnErrorCode.EXPORT_HAS_NO_DATA);
        try {
            String title = "批量导入KOC红人失败原因";
            ExcelUtils.exportExcel(outputList, title, KocStarOutputDTO.class, title + ".xlsx", response);
            stringRedisTemplate.delete(McnConstant.CACHE_PRIFIX + fileId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public String importStarBasicDataInfoExcel(List<StarBasicDataInfoInputDTO> inputList) {
        //1、校验参数
        List<String> repeatedStarCode = new ArrayList<>(inputList.size());
        List<String> repeatedIdCard = new ArrayList<>(inputList.size());
        List<StarBasicDataInfoOutputDTO> outputList = inputList.stream().map(e -> {
            StarBasicDataInfoOutputDTO outputDTO = new StarBasicDataInfoOutputDTO();
            BeanUtils.copyProperties(e, outputDTO);
            outputDTO.setFailedReason(ValidatorUtil.getJointValidateResult(outputDTO, SeparatorCst.LINE_BREAK));
            if (StringUtils.isBlank(outputDTO.getFailedReason())) {
                if (repeatedStarCode.contains(outputDTO.getStarCode())) {
                    outputDTO.setFailedReason(CommonUtil.joinWith(SeparatorCst.LINE_BREAK, outputDTO.getFailedReason(), "文件内红人ID不允许重复！"));
                } else {
                    repeatedStarCode.add(outputDTO.getStarCode());
                }
                if (repeatedIdCard.contains(outputDTO.getIdCard())) {
                    outputDTO.setFailedReason(CommonUtil.joinWith(SeparatorCst.LINE_BREAK, outputDTO.getFailedReason(), "文件内红人身份证号码重复"));
                } else if(NumberCst.ZERO.equals(e.getIdCardType()) && NumberCst.ZERO.equals(e.getStarStatus())) {
                    repeatedIdCard.add(outputDTO.getIdCard());
                }
            }
            return outputDTO;
        }).collect(Collectors.toList());
        //2、校验系统数据匹配校验
        List<String> starCodeList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getStarCode())).map(StarBasicDataInfoOutputDTO::getStarCode).distinct().collect(Collectors.toList());
        Map<String, StarBasicData> starMap = CommonUtil.getIfNecessary(CollectionUtils.isNotEmpty(starCodeList), () ->
                        CommonUtil.defaultList(starBasicDataMapper.selectList(Wrappers.lambdaQuery(StarBasicData.class)
                                .in(StarBasicData::getStarCode, starCodeList).eq(StarBasicData::getIsDelete, NumberCst.ZERO)))
                                .stream().collect(Collectors.toMap(StarBasicData::getStarCode, Function.identity()))
                , Collections.EMPTY_MAP);
        List<String> userNameList = outputList.stream().flatMap(e -> Stream.of(e.getStarAgentName(), e.getExecutorName())).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        Map<String, SUserVo> userMapping = privilegeClient.getUserMapByName(userNameList);
        outputList.forEach(e -> {
            e.verifySysDataMatch(starMap, userMapping, SeparatorCst.LINE_BREAK);
        });
        //校验红人昵称
        List<String> starNicknameList = outputList.stream().filter(e -> StringUtils.isBlank(e.getFailedReason())).map(e -> e.getStarNickname()).distinct().collect(Collectors.toList());
        Map<String, List<String>> starNicknameMap = CommonUtil.getIfNecessary(CollectionUtils.isNotEmpty(starNicknameList), () ->
                CommonUtil.defaultList(starBasicDataMapper.selectList(Wrappers.lambdaQuery(StarBasicData.class)
                        .in(StarBasicData::getStarNickname, starNicknameList).eq(StarBasicData::getIsDelete, NumberCst.ZERO)
                )).stream().collect(Collectors.groupingBy(StarBasicData::getStarNickname,
                        Collectors.mapping(StarBasicData::getStarCode, Collectors.toList()))), Collections.EMPTY_MAP);
        outputList.forEach(e -> {
            if (Objects.nonNull(e.getStarBasicData())) {
                List<String> valueList = starNicknameMap.get(e.getStarNickname());
                if (CollectionUtils.isNotEmpty(valueList)) {
                    for (String starCode : valueList) {
                        if (!starCode.equals(e.getStarCode())) {
                            e.setFailedReason(CommonUtil.joinWith(SeparatorCst.LINE_BREAK, e.getFailedReason(), "修改后红人昵称不允许重复！"));
                            break;
                        }
                    }
                }
            }
        });
        //校验身份证号
        List<String> idCardList = outputList.stream().filter(e -> StringUtils.isBlank(e.getFailedReason())
                && NumberCst.ZERO.equals(e.getIdCardType()) && NumberCst.ZERO.equals(e.getStarStatus()))
                .map(e -> e.getIdCard()).distinct().collect(Collectors.toList());
        Map<String, List<String>> idCardMap = CommonUtil.getIfNecessary(CollectionUtils.isNotEmpty(idCardList), () ->
                CommonUtil.defaultList(starBasicDataMapper.selectList(Wrappers.lambdaQuery(StarBasicData.class)
                        .in(StarBasicData::getIdCard, idCardList)
                        .eq(StarBasicData::getIdCardType, NumberCst.ZERO)
                        .eq(StarBasicData::getStarStatus, NumberCst.ZERO)
                        .eq(StarBasicData::getIsDelete, NumberCst.ZERO)
                )).stream().collect(Collectors.groupingBy(StarBasicData::getIdCard,
                        Collectors.mapping(StarBasicData::getStarCode, Collectors.toList()))), Collections.EMPTY_MAP);
        outputList.forEach(e -> {
            if (Objects.nonNull(e.getStarBasicData())) {
                List<String> valueList = idCardMap.get(e.getIdCard());
                if (CollectionUtils.isNotEmpty(valueList)) {
                    for (String starCode : valueList) {
                        if (!starCode.equals(e.getStarCode())) {
                            e.setFailedReason(CommonUtil.joinWith(SeparatorCst.LINE_BREAK, e.getFailedReason(), McnErrorCode.DUPLICATE_ID_NUMBER.getMessage()));
                            break;
                        }
                    }
                }
            }
        });
        List<StarBasicDataInfoOutputDTO> successList = outputList.stream().filter(e -> StringUtils.isBlank(e.getFailedReason())).collect(Collectors.toList());
        List<StarBasicDataInfoOutputDTO> failedList = outputList.stream().filter(e -> StringUtils.isNotBlank(e.getFailedReason())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(successList)) {
            List<OperateLogEvent> eventList = new ArrayList<>(successList.size());
            List<StarBasicData> updateList = successList.stream().map(e -> {
                StarBasicData updateStarBasicData = new StarBasicData();
                BeanUtils.copyProperties(e.getStarBasicData(), updateStarBasicData);
                updateStarBasicData.setStarStatus(e.getStarStatus());
                updateStarBasicData.setStarName(e.getStarName());
                updateStarBasicData.setStarNickname(e.getStarNickname());
                updateStarBasicData.setIdCardType(e.getIdCardType());
                updateStarBasicData.setIdCard(e.getIdCard());
                if (Objects.nonNull(e.getStarAgentId())) {
                    updateStarBasicData.setStarAgentId(e.getStarAgentId());
                    updateStarBasicData.setStarAgentName(e.getStarAgentName());
                }
                if (Objects.nonNull(e.getExecutorId())) {
                    updateStarBasicData.setExecutorId(e.getExecutorId());
                    updateStarBasicData.setExecutorName(e.getExecutorName());
                }
                updateStarBasicData.setGender(e.getGender());
                updateStarBasicData.setIsAllPlatform(e.getIsAllPlatform());
                updateStarBasicData.setUniformRebate(e.getUniformRebate());
                updateStarBasicData.setRemark(e.getRemark());
                eventList.add(OperateLogEvent.builder().businessId(updateStarBasicData.getId())
                        .businessType(LogBusinessTypeEnum.STAR_INFO)
                        .compare(e.getStarBasicData(), updateStarBasicData)
                        .build());
                return updateStarBasicData;
            }).collect(Collectors.toList());
            BaseAssemblerUtil.batchUpdateFill(updateList, UserVoContextHolder.getUserVo());
            starBasicDataMapper.saveBatch(updateList);
            EventPublisher.post(eventList);
            CommonUtil.clearList(successList, updateList);
        }
        return generateDownloadFiledId(failedList, ImportExcelEnum.UPDATE_STAR_BASIC_DATA_INFO);
    }

    /**
     * 修改红人收款账号信息
     *
     * @param starBasicDataDTO 请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void editStarAccountInfo(Long starId, StarBasicDataDTO starBasicDataDTO) throws BusinessException {
        List<StarAccountInfoVO> starAccountInfos = starBasicDataDTO.getStarAccountInfos();
        if (CollectionUtils.isNotEmpty(starAccountInfos)) {
            starAccountInfos.forEach(x -> {
                if (Objects.nonNull(x.getAlipayAccount())) {
                    verifyAlipayAccount(x.getAlipayAccount());
                }
            });
        }
        List<StarAccountInfo> infos = starAccountInfoMapper.getList(starId);
        for (StarAccountInfo starAccountInfo : starAccountInfos) {
            if (null != starAccountInfo.getId()) {
                for (StarAccountInfo oldStarAccountInfo : infos) {
                    if (starAccountInfo.getId().equals(oldStarAccountInfo.getId())) {
                        StarAccountInfo newStarAccountInfo = BaseAssemblerUtil.copyIgnoreBase(starAccountInfo, new StarAccountInfo());
                        newStarAccountInfo.setAccountName(CommonUtil.replaceBrackets(newStarAccountInfo.getAccountName()));
                        newStarAccountInfo.setCreateDate(oldStarAccountInfo.getCreateDate());
                        newStarAccountInfo.setCreateBy(oldStarAccountInfo.getCreateBy());
                        newStarAccountInfo.setCreateName(oldStarAccountInfo.getCreateName());
                        starAccountInfoMapper.updateById(newStarAccountInfo);
                        //操作日志
                        EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                .businessType(LogBusinessTypeEnum.STAR_ACCOUNT_INFO)
                                .compare(oldStarAccountInfo, newStarAccountInfo).build());
                        infos.remove(oldStarAccountInfo);
                        break;
                    }
                }
            }
        }
        List<StarAccountInfo> insertList = starAccountInfos.stream().filter(e -> Objects.isNull(e.getId())).map(e -> {
            StarAccountInfo newStarAccountInfo = BaseAssemblerUtil.copyIgnoreBase(e, new StarAccountInfo());
            newStarAccountInfo.setStarId(starId);
            newStarAccountInfo.setAccountName(CommonUtil.replaceBrackets(newStarAccountInfo.getAccountName()));
            return newStarAccountInfo;
        }).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(insertList)) {
            starAccountInfoMapper.insertBatch(insertList);
        }
        if(CollectionUtils.isNotEmpty(infos)) {
            List<Long> deleteIds = infos.stream().map(StarAccountInfo::getId).collect(Collectors.toList());
            starAccountInfoMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarAccountInfo.class)
                    .set(StarAccountInfo::getIsDelete, NumberCst.ONE)
                    .set(StarAccountInfo::getUpdateBy, UserVoContextHolder.getUserId())
                    .set(StarAccountInfo::getUpdateName, UserVoContextHolder.getUserName())
                    .set(StarAccountInfo::getUpdateDate, new Date())
                    .in(StarAccountInfo::getId, deleteIds)
                    .eq(StarAccountInfo::getIsDelete, NumberCst.ZERO));
        }
    }


    /**
     * 修改红人联系人
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void editStarContactPerson(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarContactPerson> starContactPersonList = starBasicDataDTO.getStarContactPersonList();
        if (CollectionUtils.isNotEmpty(starContactPersonList)) {
            List<StarContactPerson> infos = starContactPersonMapper.info(starId);
            for (StarContactPerson starContactPerson : starContactPersonList) {
                if (null != starContactPerson.getId()) {
                    for (StarContactPerson oldStarContactPerson : infos) {
                        if (starContactPerson.getId().equals(oldStarContactPerson.getId())) {
                            StarContactPerson newStarContactPerson = BaseAssemblerUtil.copyIgnoreBase(starContactPerson, new StarContactPerson());
                            newStarContactPerson.setStarId(starId);
                            starContactPersonMapper.updateById(newStarContactPerson);
                            //操作日志
                            EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                    .businessType(LogBusinessTypeEnum.STAR_CONTACT_PERSON)
                                    .compare(oldStarContactPerson, newStarContactPerson).build());
                            infos.remove(oldStarContactPerson);
                            break;
                        }
                    }
                }
            }
            List<StarContactPerson> insertList = starContactPersonList.stream().filter(e -> Objects.isNull(e.getId())).map(e -> {
                StarContactPerson newStarContactPerson = BaseAssemblerUtil.copyIgnoreBase(e, new StarContactPerson());
                newStarContactPerson.setStarId(starId);
                return newStarContactPerson;
            }).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(insertList)) {
                starContactPersonMapper.insertBatch(insertList);
            }
            if(CollectionUtils.isNotEmpty(infos)) {
                List<Long> deleteIds = infos.stream().map(StarContactPerson::getId).collect(Collectors.toList());
                starContactPersonMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarContactPerson.class)
                        .set(StarContactPerson::getIsDelete, NumberCst.ONE)
                        .set(StarContactPerson::getUpdateBy, UserVoContextHolder.getUserId())
                        .set(StarContactPerson::getUpdateName, UserVoContextHolder.getUserName())
                        .set(StarContactPerson::getUpdateDate, new Date())
                        .in(StarContactPerson::getId, deleteIds)
                        .eq(StarContactPerson::getIsDelete, NumberCst.ZERO));
            }
        }
    }


    /**
     * 修改红人所在平台信息
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void editStarPlatformInfo(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarPlatformInfo> starPlatformInfos = starBasicDataDTO.getStarPlatformInfos();
        if (Objects.nonNull(starPlatformInfos)) {
            List<StarPlatformInfo> infos = starPlatformInfoMapper.info(starId);
            Map<String, Map<String, String>> secondlevelDictMap = baseInfoClient.getAllSecondlevelDictMap(DictTypeCst.ACTIVE_PLATFORMS);
            for (StarPlatformInfo starPlatformInfo : starPlatformInfos) {
                // BusinessAssert.notNull(starPlatformInfo.getUserId(), McnErrorCode.PARAM_ERROR, "用户ID不能为空");
                // BusinessAssert.maxLength(starPlatformInfo.getUserId(), 500, McnErrorCode.PARAM_ERROR, "用户ID长度最大不能超出%s个字符");
                if (null != starPlatformInfo.getId()) {
                    for (StarPlatformInfo oldStarPlatformInfo : infos) {
                        if (starPlatformInfo.getId().equals(oldStarPlatformInfo.getId())) {
                            StarPlatformInfo newStarPlatformInfo = BaseAssemblerUtil.copyIgnoreBase(starPlatformInfo, new StarPlatformInfo());
                            BusinessAssert.isTrue(starPlatformInfoMapper.notExist(Wrappers.lambdaQuery(StarPlatformInfo.class)
                                    .eq(StarPlatformInfo::getStarId, starId)
                                    .eq(StarPlatformInfo::getPlatformId, newStarPlatformInfo.getPlatformId())
                                    .eq(StarPlatformInfo::getPlatNickName, newStarPlatformInfo.getPlatNickName())
                                    .ne(StarPlatformInfo::getId, newStarPlatformInfo.getId())
                                    .eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO)), McnErrorCode.PARAM_ERROR, "该红人平台已存在！");
                            starPlatformInfoMapper.update(newStarPlatformInfo, Wrappers.lambdaUpdate(StarPlatformInfo.class)
                                    .eq(StarPlatformInfo::getId, starPlatformInfo.getId())
                                    .set(StarPlatformInfo::getContractingId, starPlatformInfo.getContractingId())
                            );
                            //操作日志
                            EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                    .businessType(LogBusinessTypeEnum.STAR_PLATFORM_INFO)
                                    .compare(oldStarPlatformInfo, newStarPlatformInfo).remark(String.format(LogTemplateCst.STAR_PLATFORM, newStarPlatformInfo.getPlatformName())).build());
                            infos.remove(oldStarPlatformInfo);
                            break;
                        }
                    }
                } else {
                    StarPlatformInfo newStarPlatformInfo = BaseAssemblerUtil.copyIgnoreBase(starPlatformInfo, new StarPlatformInfo());
                    BusinessAssert.isTrue(starPlatformInfoMapper.notExist(Wrappers.lambdaQuery(StarPlatformInfo.class)
                            .eq(StarPlatformInfo::getStarId, starId)
                            .eq(StarPlatformInfo::getPlatformId, newStarPlatformInfo.getPlatformId())
                            .eq(StarPlatformInfo::getPlatNickName, newStarPlatformInfo.getPlatNickName())
                            .eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO)), McnErrorCode.PARAM_ERROR, "该红人平台已存在！");
                    newStarPlatformInfo.setStarId(starId);
                    starPlatformInfoMapper.insert(newStarPlatformInfo);
                    starPlatformInfo.setId(newStarPlatformInfo.getId());
                }
                dealPlatformSettlementData(starId, secondlevelDictMap, starPlatformInfo);
            }
            if(CollectionUtils.isNotEmpty(infos)) {
                List<Long> deleteIds = infos.stream().map(StarPlatformInfo::getId).collect(Collectors.toList());
                starPlatformInfoMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarPlatformInfo.class)
                        .set(StarPlatformInfo::getIsDelete, NumberCst.ONE)
                        .set(StarPlatformInfo::getUpdateBy, UserVoContextHolder.getUserId())
                        .set(StarPlatformInfo::getUpdateName, UserVoContextHolder.getUserName())
                        .set(StarPlatformInfo::getUpdateDate, new Date())
                        .in(StarPlatformInfo::getId, deleteIds)
                        .eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO));
            }
        }
    }

    private void dealPlatformSettlementData(Long starId, Map<String, Map<String, String>> secondlevelDictMap, StarPlatformInfo starPlatformInfo) {
        log.info("dealPlatformSettlementData --> start");
        UserVO userVo = UserVoContextHolder.getUserVo();
        List<StarPlatformSettlementInfo> settlementInfos = starPlatformInfo.getSettlementInfos();
        //根据平台id获取所有结算信息
        List<StarPlatformSettlementInfo> spsList = starPlatformSettlementInfoMapper.selectList(Wrappers.lambdaQuery(StarPlatformSettlementInfo.class)
                .eq(StarPlatformSettlementInfo::getStarPlatformInfoId, starPlatformInfo.getId()).eq(StarPlatformSettlementInfo::getIsDelete, Boolean.FALSE));
        if(CollectionUtils.isNotEmpty(spsList) && MapUtils.isNotEmpty(secondlevelDictMap)) {
            spsList.forEach(settlementInfo -> {
                settlementInfo.setCooperationContentName(CommonUtil.getMapValue(secondlevelDictMap.get(starPlatformInfo.getPlatformId()), settlementInfo.getCooperationContent()));
            });
        }
        Map<Long, StarPlatformSettlementInfo> spsMap = CommonUtil.defaultList(spsList).stream().collect(Collectors.toMap(StarPlatformSettlementInfo::getId, Function.identity()));
        List<Long> needUpdateSettlementIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(settlementInfos)) {
            for (StarPlatformSettlementInfo settlementInfo : settlementInfos) {
                Long settlementId = settlementInfo.getId();
                if (Objects.nonNull(settlementId)) {
                    //原有平台变更结算信息，需要对比当前参数与数据库中的数据进行处理
                    if (spsMap.containsKey(settlementId)) {
                        StarPlatformSettlementInfo before = spsMap.get(settlementId);
                        before.setSpsInfo(String.format(LogTemplateCst.STAR_PLATFORM_SETTLEMENT_UPDATE, starPlatformInfo.getPlatformName(),
                                before.getCooperationContentName(), CommonUtil.yesOrNo(before.getInSystemAdmin())));
                        settlementInfo.setUpdateBy(userVo.getUserId());
                        settlementInfo.setUpdateDate(new Date());
                        settlementInfo.setUpdateName(userVo.getRealName());
                        starPlatformSettlementInfoMapper.updateById(settlementInfo);
                        needUpdateSettlementIds.add(settlementId);
                        settlementInfo.setCooperationContentName(CommonUtil.getMapValue(secondlevelDictMap.get(starPlatformInfo.getPlatformId()),
                                settlementInfo.getCooperationContent()));
                        settlementInfo.setSpsInfo(String.format(LogTemplateCst.STAR_PLATFORM_SETTLEMENT_UPDATE, starPlatformInfo.getPlatformName(),
                                settlementInfo.getCooperationContentName(), CommonUtil.yesOrNo(settlementInfo.getInSystemAdmin())));
                        //操作日志
                        EventPublisher.post(OperateLogEvent.builder().businessId(starId).businessType(LogBusinessTypeEnum.STAR_PLATFORM_INFO)
                                .compare(before, settlementInfo).build());
                    }
                } else {
                    settlementInfo.setStarPlatformInfoId(starPlatformInfo.getId());
                    starPlatformSettlementInfoMapper.insert(settlementInfo);
                    needUpdateSettlementIds.add(settlementInfo.getId());
                }
            }
            if (CollUtil.isNotEmpty(needUpdateSettlementIds)) {
                //删除
                starPlatformSettlementInfoMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarPlatformSettlementInfo.class)
                        .notIn(StarPlatformSettlementInfo::getId, needUpdateSettlementIds)
                        .eq(StarPlatformSettlementInfo::getStarPlatformInfoId, starPlatformInfo.getId())
                        .set(StarPlatformSettlementInfo::getUpdateBy, userVo.getUserId())
                        .set(StarPlatformSettlementInfo::getUpdateName, userVo.getRealName())
                        .set(StarPlatformSettlementInfo::getUpdateDate, new Date())
                        .set(StarPlatformSettlementInfo::getIsDelete, NumberCst.ONE));
            }
        } else {
            //平台下所有结算信息全被清空，所关联的结算信息需要被全部删除
            starPlatformSettlementInfoMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarPlatformSettlementInfo.class)
                    .eq(StarPlatformSettlementInfo::getStarPlatformInfoId, starPlatformInfo.getId())
                    .set(StarPlatformSettlementInfo::getUpdateBy, userVo.getUserId())
                    .set(StarPlatformSettlementInfo::getUpdateName, userVo.getRealName())
                    .set(StarPlatformSettlementInfo::getUpdateDate, new Date())
                    .set(StarPlatformSettlementInfo::getIsDelete, NumberCst.ONE));

        }
        log.info("dealPlatformSettlementData --> end");
    }

    /**
     * 修改红人签约合同
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void editStarContract(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarContractVO> starContracts = starBasicDataDTO.getStarContracts();
        if (CollectionUtils.isNotEmpty(starContracts)) {
            checkSignContractNos(starContracts);
            List<StarContract> starContractList = starContractMapper.selectList(Wrappers.lambdaQuery(StarContract.class)
                    .eq(StarContract::getStarId, starId).eq(StarContract::getIsDelete, NumberCst.ZERO));
            Map<Long, StarContract> starContractMap = CommonUtil.defaultList(starContractList).stream().collect(Collectors.toMap(StarContract::getId, Function.identity()));
            List<StarContractDetail> starContractDetailList = starContractDetailMapper.selectList(Wrappers.lambdaQuery(StarContractDetail.class)
                    .eq(StarContractDetail::getStarId, starId).eq(StarContractDetail::getIsDelete, NumberCst.ZERO));
            Map<Long, List<StarContractDetail>> starContractDetailMap = CommonUtil.defaultList(starContractDetailList).stream().collect(Collectors.groupingBy(StarContractDetail::getStarContractId));
            for (StarContractVO starContractVO : starContracts) {
                if(Objects.isNull(starContractVO.getId())) {
                    this.insertStarContractAndDetails(starId, starContractVO);
                    continue;
                }
                if(starContractMap.containsKey(starContractVO.getId())) {
                    StarContract oldStarContract = starContractMap.get(starContractVO.getId());
                    StarContract newStarContract = BaseAssemblerUtil.copyIgnoreBase(starContractVO, new StarContract());
                    newStarContract.setId(starContractVO.getId());
                    newStarContract.setContractType(starContractVO.getContractType());
                    newStarContract.setRemark(starContractVO.getRemark());
                    newStarContract.setContract(starContractVO.getContract());
                    if (Objects.nonNull(starContractVO.getSignContractNo()) && !starContractVO.getSignContractNo().equals(oldStarContract.getSignContractNo())) {
                        verifyUpdateSignContractNo(starContractVO.getSignContractNo(), starContractVO.getId());
                        newStarContract.setSignContractNo(starContractVO.getSignContractNo());
                    }
                    starContractMapper.updateById(newStarContract);
                    //操作日志
                    EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                            .businessType(LogBusinessTypeEnum.STAR_CONTRACT)
                            .compare(oldStarContract, newStarContract)
                            .build());
                    if(CollectionUtils.isNotEmpty(starContractVO.getStarContractDetails())) {
                        List<StarContractDetail> oldStarContractDetails = starContractDetailMap.get(starContractVO.getId());
                        Map<Long, StarContractDetail> oldStarContractDetailMap = CommonUtil.defaultList(oldStarContractDetails).stream().collect(Collectors.toMap(StarContractDetail::getId, Function.identity()));
                        List<Long> updateIds = CommonUtil.defaultList(starContractVO.getStarContractDetails()).stream().map(StarContractDetail::getId).filter(Objects::nonNull).collect(Collectors.toList());
                        List<StarContractDetail> deleteList = CommonUtil.defaultList(oldStarContractDetails).stream().filter(e -> !updateIds.contains(e.getId())).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(deleteList)) {
                            List<Long> deleteIds = deleteList.stream().map(StarContractDetail::getId).collect(Collectors.toList());
                            //操作日志
                            CommonUtil.defaultList(starContractDetailMapper.getStarContractDetails(deleteIds)).forEach(e -> {
                                EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                        .businessType(LogBusinessTypeEnum.STAR_CONTRACT)
                                        .delete(LogTemplateCst.SIGN_CONTRACT_DETAIL_DELETE, e.getPlatformName(), e.getPlatNickName(), e.getDividedRate(),
                                                e.getDividedRemark(), DateUtils.formatDate(e.getSigningStartTime()),DateUtils.formatDate(e.getSigningEndTime()))
                                        .build());
                            });
                            //删除签约合同明细
                            starContractDetailMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarContractDetail.class)
                                    .set(StarContractDetail::getIsDelete, NumberCst.ONE)
                                    .set(StarContractDetail::getUpdateBy, UserVoContextHolder.getUserId())
                                    .set(StarContractDetail::getUpdateName, UserVoContextHolder.getUserName())
                                    .set(StarContractDetail::getUpdateDate, new Date())
                                    .in(StarContractDetail::getId, deleteIds)
                                    .eq(StarContractDetail::getIsDelete, NumberCst.ZERO));
                        }
                        //修改签约明细
                        for(StarContractDetailVO detailVO : starContractVO.getStarContractDetails()) {
                            if(Objects.nonNull(detailVO.getId())) {
                                StarContractDetail oldStarContractDetail = oldStarContractDetailMap.get(detailVO.getId());
                                StarContractDetail newStarContractDetail = BaseAssemblerUtil.copyIgnoreBase(detailVO, new StarContractDetail());
                                newStarContractDetail.setStarContractId(newStarContract.getId());
                                newStarContractDetail.setStarId(newStarContract.getStarId());
                                starContractDetailMapper.updateById(newStarContractDetail);
                                //操作日志
                                EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                        .businessType(LogBusinessTypeEnum.STAR_CONTRACT)
                                        .compare(oldStarContractDetail, newStarContractDetail).build());
                            }
                        }
                        //签约合同明细
                        List<StarContractDetail> insertDetails = CommonUtil.defaultList(starContractVO.getStarContractDetails()).stream().filter(e -> Objects.isNull(e.getId())).map(e -> {
                            StarContractDetail starContractDetail = BaseAssemblerUtil.copyIgnoreBase(e, new StarContractDetail());
                            starContractDetail.setStarContractId(newStarContract.getId());
                            starContractDetail.setStarId(newStarContract.getStarId());
                            return starContractDetail;
                        }).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(insertDetails)) {
                            starContractDetailMapper.insertBatch(insertDetails);
                        }
                    }
                }
            }
            List<Long> starContractIds = starContracts.stream().map(StarContractVO::getId).filter(Objects::nonNull).collect(Collectors.toList());
            List<StarContract> deleteList = CommonUtil.defaultList(starContractList).stream().filter(e -> !starContractIds.contains(e.getId())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(deleteList)) {
                List<Long> deleteIds = deleteList.stream().map(StarContract::getId).collect(Collectors.toList());
                //删除签约合同
                starContractMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarContract.class)
                        .set(StarContract::getIsDelete, NumberCst.ONE)
                        .set(StarContract::getUpdateBy, UserVoContextHolder.getUserId())
                        .set(StarContract::getUpdateName, UserVoContextHolder.getUserName())
                        .set(StarContract::getUpdateDate, new Date())
                        .in(StarContract::getId, deleteIds)
                        .eq(StarContract::getIsDelete, NumberCst.ZERO));
                //删除签约合同明细
                starContractDetailMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarContractDetail.class)
                        .set(StarContractDetail::getIsDelete, NumberCst.ONE)
                        .set(StarContractDetail::getUpdateBy, UserVoContextHolder.getUserId())
                        .set(StarContractDetail::getUpdateName, UserVoContextHolder.getUserName())
                        .set(StarContractDetail::getUpdateDate, new Date())
                        .in(StarContractDetail::getStarContractId, deleteIds)
                        .eq(StarContractDetail::getIsDelete, NumberCst.ZERO));
                //操作日志
                deleteList.forEach(e -> {
                    //操作日志
                    EventPublisher.post(OperateLogEvent.builder().businessId(starId).businessType(LogBusinessTypeEnum.STAR_CONTRACT)
                            .delete(LogTemplateCst.SIGN_CONTRACT_DELETE, e.getSignContractNo()).build());
                });
            }
            this.judgeConflictingSignContract(starId);
        }
    }

    /**
     * 插入签约合同及明细
     * @param starId
     * @param starContractVO
     */
    private void insertStarContractAndDetails(Long starId, StarContractVO starContractVO) {
        StarContract newStarContract = BaseAssemblerUtil.copyIgnoreBase(starContractVO, new StarContract());
        if (Objects.nonNull(newStarContract.getSignContractNo())) {
            verifySignContractNo(newStarContract.getSignContractNo());
        }
        newStarContract.setStarId(starId);
        newStarContract.setState(NumberCst.ZERO);
        newStarContract.setRelieveTime(null);
        starContractMapper.insert(newStarContract);
        if(CollectionUtils.isNotEmpty(starContractVO.getStarContractDetails())) {
            List<StarContractDetail> detailList = starContractVO.getStarContractDetails().stream().map(e -> {
                StarContractDetail starContractDetail = BaseAssemblerUtil.copyIgnoreBase(e, new StarContractDetail());
                starContractDetail.setStarContractId(newStarContract.getId());
                starContractDetail.setStarId(newStarContract.getStarId());
                return starContractDetail;
            }).collect(Collectors.toList());
            starContractDetailMapper.insertBatch(detailList);
        }
    }


    /**
     * 修改红人开票抬头
     *
     * @param starId           红人id
     * @param starBasicDataDTO 入参
     */
    private void editStarBillingHeader(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarBillingHeader> starBillingHeaders = starBasicDataDTO.getStarBillingHeaders();
        if (CollectionUtils.isNotEmpty(starBillingHeaders)) {
            List<StarBillingHeader> headerList = starBillingHeaderMapper.selectList(Wrappers.lambdaQuery(StarBillingHeader.class)
                    .eq(StarBillingHeader::getStarId, starId).eq(StarBillingHeader::getIsDelete, Boolean.FALSE));
            for (StarBillingHeader starBillingHeader : starBillingHeaders) {
                if (null != starBillingHeader.getId()) {
                    for (StarBillingHeader oldStarBillingHeader : headerList) {
                        if (starBillingHeader.getId().equals(oldStarBillingHeader.getId())) {
                            StarBillingHeader newStarBillingHeader = BaseAssemblerUtil.copyIgnoreBase(starBillingHeader, new StarBillingHeader());
                            BeanUtils.copyProperties(starBillingHeader, newStarBillingHeader);
                            starBillingHeaderMapper.updateById(newStarBillingHeader);
                            //操作日志
                            EventPublisher.post(OperateLogEvent.builder().businessId(starId)
                                    .businessType(LogBusinessTypeEnum.STAR_BILLING_HEADER)
                                    .compare(oldStarBillingHeader,  newStarBillingHeader)
                                    .build());
                            headerList.remove(oldStarBillingHeader);
                            break;
                        }
                    }
                }
            }
            List<StarBillingHeader> insertList = starBillingHeaders.stream().filter(e -> Objects.isNull(e.getId())).map(e -> {
                StarBillingHeader billingHeader = BaseAssemblerUtil.copyIgnoreBase(e, new StarBillingHeader());
                billingHeader.setStarId(starId);
                billingHeader.setHeaderName(StringUtils.defaultString(billingHeader.getHeaderName()));
                billingHeader.setTaxpayerIdentificationNumber(StringUtils.defaultString(billingHeader.getTaxpayerIdentificationNumber()));
                billingHeader.setBillingPhone(StringUtils.defaultString(billingHeader.getBillingPhone()));
                billingHeader.setBillingAddress(StringUtils.defaultString(billingHeader.getBillingAddress()));
                billingHeader.setAccountsBank(StringUtils.defaultString(billingHeader.getAccountsBank()));
                billingHeader.setAccountNumber(StringUtils.defaultString(billingHeader.getAccountNumber()));
                billingHeader.setIsEnable(ObjectUtils.defaultIfNull(billingHeader.getIsEnable(), NumberCst.ZERO));
                return billingHeader;
            }).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(insertList)) {
                starBillingHeaderMapper.insertBatch(insertList);
            }
            if(CollectionUtils.isNotEmpty(headerList)) {
                List<Long> deleteIds = headerList.stream().map(StarBillingHeader::getId).collect(Collectors.toList());
                starBillingHeaderMapper.updateByNoStrategy(Wrappers.lambdaUpdate(StarBillingHeader.class)
                        .set(StarBillingHeader::getIsDelete, NumberCst.ONE)
                        .set(StarBillingHeader::getUpdateBy, UserVoContextHolder.getUserId())
                        .set(StarBillingHeader::getUpdateName, UserVoContextHolder.getUserName())
                        .set(StarBillingHeader::getUpdateDate, new Date())
                        .in(StarBillingHeader::getId, deleteIds)
                        .eq(StarBillingHeader::getIsDelete, NumberCst.ZERO));
            }
        }
    }


    /**
     * 组装主表信息
     *
     * @param starBasicData 请求参数
     * @return 返回值
     */
    public int assemblyStarBasicData(StarBasicData starBasicData) {
        starBasicData.setStarCode(CodeGenerateHelper.getCode(BillCodeCst.STAR_BASIC));
        starBasicData.setStarStatus(0);
        return starBasicDataMapper.insert(starBasicData);
    }

    /**
     * 组装红人收款账号信息
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void assemblyStarAccountInfo(Long starId, StarBasicDataDTO starBasicDataDTO) throws BusinessException {
        List<StarAccountInfoVO> starAccountInfos = starBasicDataDTO.getStarAccountInfos();
        if (Objects.nonNull(starAccountInfos)) {
            for (StarAccountInfo starAccountInfo : starAccountInfos) {
                if (StringUtils.isNotBlank(starAccountInfo.getAlipayAccount())) {
                    verifyAlipayAccount(starAccountInfo.getAlipayAccount());
                }
                starAccountInfo.setAccountName(CommonUtil.replaceBrackets(starAccountInfo.getAccountName()));
                starAccountInfo.setStarId(starId);
                starAccountInfoMapper.insert(starAccountInfo);
            }
        }
    }


    public void verifyAlipayAccount(String alipayAccount) {
        if (alipayAccount.length() > THIRTY) {
            throw new BusinessException(McnErrorCode.ALIPAY_ACCOUNT_LENGTH);
        }
    }

    /**
     * 组装红人联系人数据
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void assemblyStarContactPerson(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarContactPerson> starContactPersonList = starBasicDataDTO.getStarContactPersonList();
        if (Objects.nonNull(starContactPersonList)) {
            for (StarContactPerson starContactPerson : starContactPersonList) {
                starContactPerson.setStarId(starId);
                starContactPersonMapper.insert(starContactPerson);
            }
        }
    }


    /**
     * 组装红人所在平台信息
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    public void assemblyStarPlatformInfo(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarPlatformInfo> starPlatformInfos = starBasicDataDTO.getStarPlatformInfos();
        if (Objects.nonNull(starPlatformInfos)) {
            for (StarPlatformInfo starPlatformInfo : starPlatformInfos) {
                // BusinessAssert.notNull(starPlatformInfo.getUserId(), McnErrorCode.PARAM_ERROR, "用户ID不能为空");
                // BusinessAssert.maxLength(starPlatformInfo.getUserId(), 500, McnErrorCode.PARAM_ERROR, "用户ID长度最大不能超出%s个字符");
                BusinessAssert.isTrue(starPlatformInfoMapper.notExist(Wrappers.lambdaQuery(StarPlatformInfo.class)
                        .eq(StarPlatformInfo::getStarId, starId)
                        .eq(StarPlatformInfo::getPlatformId, starPlatformInfo.getPlatformId())
                        .eq(StarPlatformInfo::getPlatNickName, starPlatformInfo.getPlatNickName())
                        .eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO)), McnErrorCode.PARAM_ERROR, "该红人平台已存在！");
                starPlatformInfo.setStarId(starId);
                starPlatformInfo.setPlatformStatus(ObjectUtils.defaultIfNull(starPlatformInfo.getPlatformStatus(), NumberCst.ZERO));
                starPlatformInfoMapper.insert(starPlatformInfo);
                dealPlatformSettlementData(starId, null, starPlatformInfo);
            }
        }
    }

    /**
     * 组装红人签约合同
     *
     * @param starId           请求参数
     * @param starBasicDataDTO 请求参数
     */
    private void assemblyStarContract(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarContractVO> starContracts = starBasicDataDTO.getStarContracts();
        if (CollectionUtils.isNotEmpty(starContracts)) {
            checkSignContractNos(starContracts);
            for (StarContractVO starContract : starContracts) {
                this.insertStarContractAndDetails(starId, starContract);
            }
        }
        this.judgeConflictingSignContract(starId);
    }


    /**
     * 组装红人开票抬头
     *
     * @param starId           红人id
     * @param starBasicDataDTO 传参
     */
    private void assemblyStarBillingHeader(Long starId, StarBasicDataDTO starBasicDataDTO) {
        List<StarBillingHeader> starBillingHeaders = starBasicDataDTO.getStarBillingHeaders();
        if (CollectionUtils.isNotEmpty(starBillingHeaders)) {
            starBillingHeaders.forEach(x -> {
                x.setStarId(starId);
                starBillingHeaderMapper.insert(x);
            });
        }
    }

    private void checkSignContractNos(List<StarContractVO> starContracts) {
        List<String> repeatedSignContractNo = starContracts.stream().filter(e -> !NumberCst.ONE.equals(e.getState())).collect(Collectors.groupingBy(StarContractVO::getSignContractNo, Collectors.counting()))
                .entrySet().stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey()).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(repeatedSignContractNo)) {
            throw new BusinessException(McnErrorCode.ALIPAY_ACCOUNT_REPEAT.code(), String.format("红人签约合同编号【%s】重复", StringUtils.join(repeatedSignContractNo, SeparatorCst.COMMA)));
        }

    }


    public void verifySignContractNo(String signContractNo) {
        if (StringUtils.isNotBlank(signContractNo)) {
            List<StarContract> starContracts = starContractMapper.selectList(Wrappers.lambdaQuery(StarContract.class)
                    .eq(StarContract::getIsDelete, NumberCst.ZERO)
                    .eq(StarContract::getState, NumberCst.ZERO)
                    .eq(StarContract::getSignContractNo, signContractNo));
            if (starContracts.size() > 0) {
                throw new BusinessException(McnErrorCode.SIGN_CONTRACT_EXISTED.code(), String.format("红人签约合同编号【%s】已存在", signContractNo));
            }
        }
    }


    public void verifyUpdateSignContractNo(String signContractNo, Long id) {
        if (StringUtils.isNotBlank(signContractNo)) {
            List<StarContract> starContracts = starContractMapper.selectList(Wrappers.lambdaQuery(StarContract.class)
                    .eq(StarContract::getIsDelete, NumberCst.ZERO)
                    .eq(StarContract::getState, NumberCst.ZERO)
                    .eq(StarContract::getSignContractNo, signContractNo));
            if (starContracts.size() > 0) {
                starContracts.forEach(x -> {
                    if (!x.getId().equals(id)) {
                        throw new BusinessException(McnErrorCode.SIGN_CONTRACT_EXISTED.code(), String.format("红人签约合同编号【%s】已存在", signContractNo));
                    }
                });
            }
        }
    }

    /**
     * 按红人类型校验红人昵称是否重复
     *
     * @param starType     {@link Integer}
     * @param starNickname {@link String}
     * @param starId       {@link Long}
     */
    private void verifyDuplicateNickname(String starNickname, Integer starType, Long starId) {
        BusinessAssert.isTrue(starBasicDataMapper.selectCount(Wrappers.lambdaQuery(StarBasicData.class)
                .eq(StarBasicData::getStarType, starType)
                .eq(StarBasicData::getStarNickname, starNickname)
                .ne(starId != null, StarBasicData::getId, starId)
                .eq(StarBasicData::getIsDelete, Boolean.FALSE)) == 0, McnErrorCode.DUPLICATE_CELEBRITY_NICKNAME);
    }

    /**
     * 按红人类型校验红人身份证是否重复
     *
     * @param idCardType {@link Integer}
     * @param idCard     {@link String}
     * @param starId     {@link Long}
     */
    private void verifyDuplicateIdNumber(Integer idCardType, String idCard, Long starId) {
        if (Objects.nonNull(idCardType) && idCardType == 0 && StringUtils.isNotEmpty(idCard)) {
            BusinessAssert.isTrue(starBasicDataMapper.selectCount(Wrappers.lambdaQuery(StarBasicData.class)
                    .eq(StarBasicData::getIdCard, idCard)
                    .eq(StarBasicData::getIdCardType, NumberCst.ZERO)
                    .eq(StarBasicData::getStarStatus, NumberCst.ZERO)
                    .ne(starId != null, StarBasicData::getId, starId)
                    .eq(StarBasicData::getIsDelete, Boolean.FALSE)) == 0, McnErrorCode.DUPLICATE_ID_NUMBER);
        }
    }

    /**
     * 校验红人类型变更
     *
     * @param starId      {@link Long}
     * @param oldStarType {@link Integer}
     * @param newStarType {@link Integer}
     */
    private void verifyChangeStarType(Long starId, Integer oldStarType, Integer newStarType) {
        if (!oldStarType.equals(newStarType)) {
            BusinessAssert.isTrue(contractExcutionOrderMapper.selectCount(Wrappers.lambdaQuery(ContractExcutionOrder.class)
                    .eq(ContractExcutionOrder::getStarId, starId)
                    .ne(ContractExcutionOrder::getApprovalStatus, ExcutionApprovalStatusEnum.INVALID)
                    .eq(ContractExcutionOrder::getIsDelete, Boolean.FALSE)
            ) == 0, McnErrorCode.NOT_ALLOWED_CHANGE_STAR_TYPE);
        }
    }

    /**
     * 生成下载失败的文件信息ID
     *
     * @param outputList
     * @param excelEnum
     * @return
     */
    private <T> String generateDownloadFiledId(List<T> outputList, ImportExcelEnum excelEnum) {
        if (CollectionUtils.isEmpty(outputList)) {
            return null;
        }
        String fileId = excelEnum.getFileId();
        stringRedisTemplate.opsForValue().set(McnConstant.CACHE_PRIFIX + fileId, JSONObject.toJSONString(outputList), 30, TimeUnit.DAYS);
        outputList.clear();
        return fileId;
    }

    /**
     *
     * @param starContractDetails
     * @return
     */
    private boolean withInTimeRange(Date now , List<StarContractDetailVO> starContractDetails) {
        if(CollectionUtils.isEmpty(starContractDetails)) {
            return false;
        }
        for(StarContractDetailVO vo : starContractDetails) {
            if(!now.before(vo.getSigningStartTime()) && !now.after(vo.getSigningEndTime())) {
                return true;
            }
        }
        return false;
    }

    /**
     *
     * @param starContractDetails
     * @return
     */
    private boolean beforeTimeRange(Date now , List<StarContractDetailVO> starContractDetails) {
        if(CollectionUtils.isEmpty(starContractDetails)) {
            return false;
        }
        for(StarContractDetailVO vo : starContractDetails) {
            if(!vo.getSigningEndTime().before(now)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 平台签约周期冲突判断
     * @param starId
     */
    private void judgeConflictingSignContract(Long starId) {
        List<Long> starPlatformIds = starContractDetailMapper.getConflictingStarPlatformIds(starId);
        if(CollectionUtils.isNotEmpty(starPlatformIds)) {
            List<StarPlatformInfo> starPlatformInfoList = starPlatformInfoMapper.selectList(Wrappers.lambdaQuery(StarPlatformInfo.class)
                    .in(StarPlatformInfo::getId, starPlatformIds).eq(StarPlatformInfo::getIsDelete, NumberCst.ZERO));
            BusinessAssert.notEmpty(starPlatformInfoList,"该红人平台签约周期冲突时，查询不到对应的红人平台信息");
            String joinStarPlaformName = CommonUtil.defaultList(starPlatformInfoList).stream().map(StarPlatformInfo::getPlatformName).collect(Collectors.joining(SeparatorCst.COMMA));
            throw new BusinessException(McnErrorCode.BUSINESS_ERROR.code(), String.format("该红人在【%s】平台签约周期冲突，请修改后操作", joinStarPlaformName));
        }
    }
}
